package com.lottery.game.websocket;

import com.alibaba.fastjson.JSONObject;
import com.lottery.game.common.constants.GameConstants;
import com.lottery.game.common.utils.DateUtils;
import com.lottery.game.core.modules.entity.user.ChatRecord;
import com.lottery.game.core.modules.entity.user.GameUser;
import com.lottery.game.core.modules.entity.user.RealNumber;
import com.lottery.game.core.modules.service.app.ChatRecordService;
import com.lottery.game.core.modules.service.app.GameUserService;
import com.lottery.game.core.modules.service.app.OperationalSetService;
import com.lottery.game.core.modules.service.redis.RedisService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyHandler extends TextWebSocketHandler implements Serializable {

	private static final long serialVersionUID = 1L;

	public static Map<String, Map<String, WebSocketSession>> webSocketMap = new HashMap<String, Map<String, WebSocketSession>>();


	/** 日志 */
//	private static Logger logger = LoggerFactory.getLogger(MyHandler.class);

	@Autowired
	private ChatRecordService chatRecordService;

	@Autowired
	private GameUserService gameUserService;

	@Autowired
	private OperationalSetService operationalSetService;

	@Autowired
	private RedisService redisFeignClient;

	/**
	 * 发消息处理
	 */
	@Override
	public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

		String chartId = (String) session.getAttributes().get("chartId");

		//后台管理系统 WS心跳处理
		if(GameConstants.WEBSOCKET_SYSTEM_HEART.equals(message.getPayload())){
			JSONObject object = new JSONObject();
			//如果后台管理系统发送了心跳请求，后台回复一条约定好的心跳回执
			object.put("msg",GameConstants.WEBSOCKET_SERVER_HEART);
			session.sendMessage(new TextMessage(object.toJSONString()));
			return;
		}

		// 消息类型
		String chatType = (String) session.getAttributes().get("chatType");
		String userId = (String) session.getAttributes().get("userId");

		// 构建消息数据
		ChatRecord chatRecord = new ChatRecord();
		UUID uuid = UUID.randomUUID();
		chatRecord.setId(uuid.toString());
		chatRecord.setChatType(chatType);
		chatRecord.setSenderUserid(userId);

		log.info("---message.getPayload:   {}", message.getPayload());
		chatRecord.setMsgContent(message.getPayload());
        chatRecord.setMessageStatus("0");
		chatRecord.setTimestamp(DateUtils.getNowDateString());

		//用户禁言状态，默认否
		boolean userBanned = false;
		// 房间群聊
		if (GameConstants.CHATTYPE_GROUPCHAT.equals(chatType)) {
			chatRecord.setRoomnumber(chartId);
			GameUser user = gameUserService.get(userId);
			if (user != null) {
			    chatRecord.setSenderPhone(user.getPhone());
                chatRecord.setSendernickname(user.getUsername());
                chatRecord.setSenderphoto(user.getPhotourl());

			} else {
				chatRecord.setSenderPhone("null");
				chatRecord.setSendernickname(userId);
			}

		// 客服聊天
		} else if (GameConstants.CHATTYPE_CUSSERVICECHAT.equals(chatType)) {
			GameUser user = gameUserService.get(userId);
			chatRecord.setSenderUserid(userId);
			if (user != null) {
				// 判断用户的禁言状态
				chatRecord.setSenderPhone(user.getPhone());
				chatRecord.setSendernickname(user.getUsername());
				chatRecord.setSenderphoto(user.getPhotourl());


			} else {
				chatRecord.setSenderPhone("null");
				chatRecord.setSendernickname(userId);
			}
			//用户前端发放消息给客服时,推送一条通知给后端服务器
			Map<String, String> map = new HashMap<>(16);
			map.put("sendUserId", userId);
			TextMessage cusserviceNoticeMsg = new TextMessage(JSONObject.toJSONString(map));
//			MyHandler.sendMessageToAllUser(GameConstants.SYS_MSG_CUSSERVICECHAT_NOTICE, cusserviceNoticeMsg);

		//客服回复
		}else if(GameConstants.CHATTYPE_CUSREPLY.equals(chatType)) {
		    //TODO 管理员账户获取
		    chatRecord.setSenderPhone("null");
            chatRecord.setSendernickname(userId);
            chatRecord.setReceiverUserid(chartId);

		// 系统websocket连接，默认不允许用户推送消息到后台，防止插入数据库影响数据
		}else if(GameConstants.CHATTYPE_SYSTEM_MSG.equals(chatType)) {
		    userBanned = true;
		}
/*		else if(GameConstants.CHAT_TYPE_ROOM_MSG.equals(chatType)){
			String roomId = (String) session.getAttributes().get("roomId");
			chatRecord.setRoomnumber(roomId);
		}*/

		// 构建消息
		TextMessage sendMsg = new TextMessage(JSONObject.toJSONString(chatRecord));


			//没有禁言的用户才数据插入以及推送操作
			if (!StringUtils.isEmpty(chartId)&&!userBanned) {
				Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
				if (sessionMap != null) {
					Iterator<Entry<String, WebSocketSession>> it = sessionMap.entrySet().iterator();
					while (it.hasNext()) {
						Entry<String, WebSocketSession> tmpSession = it.next();
						if (!tmpSession.getKey().equals(userId)) {
							sendMessageToUser(tmpSession.getValue(), sendMsg);
							chatRecord.setMessageStatus("1");
						}
					}
					String orginMsg = "";
					try {
						JSONObject obj = JSONObject.parseObject(chatRecord.getMsgContent());
						orginMsg = obj.getString("message");
						chatRecord.setOrginMsg(orginMsg);
						Boolean  isBetsSend = obj.getBoolean("betsSend");
						if(isBetsSend!=null) {
							if (isBetsSend) {
								chatRecord.setGameroomId("betsSend");
							}
						}
					}catch(Exception e) {
						e.printStackTrace();
					}
					// 存入数据库
					chatRecordService.addChatRecord(chatRecord);
				}
			}
	}

	/**
	 * 成功连接
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		String chartId = (String) session.getAttributes().get("chartId");
		String userId = (String) session.getAttributes().get("userId");
		String chartType = "";
		if ( null == chartId){
			URI uri = session.getUri();
			String query = uri.getQuery();
			String[] split = null;
			if (null != query){
				split = query.split("&");
				if (null != split){
					for (String s : split) {
						String[] equalStrtemp = s.split("=");
						if ("chatType".equals(equalStrtemp[0])){
							chartId = equalStrtemp[1];
						}else if ("userId".equals(equalStrtemp[0])){
							userId = equalStrtemp[1];
						}
					}
				}

			}
		}
		if(chartId != null && chartId.equals(GameConstants.SYS_OVERALL)) {
			Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
			if (sessionMap == null) {
				sessionMap = new HashMap<String, WebSocketSession>();
			}
			String randomUserId=(String) session.getAttributes().get("randomUserId");
			sessionMap.put(randomUserId, session);
			webSocketMap.put(chartId, sessionMap);
			//上分
		}else if (chartId != null && GameConstants.SYS_MSG_SXFEN_COUNT.equals(chartId)){
			Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
			if (sessionMap == null) {
				sessionMap = new HashMap<String, WebSocketSession>();
			}
			sessionMap.put(userId, session);
			webSocketMap.put(chartId, sessionMap);
			JSONObject object = new JSONObject();
			// 如果后台管理系统发送了心跳请求，后台回复一条约定好的心跳回执
			object.put("msg", GameConstants.WEBSOCKET_SERVER_HEART);
			session.sendMessage(new TextMessage(object.toJSONString()));
		}else {
		Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
		if (sessionMap == null) {
			sessionMap = new HashMap<String, WebSocketSession>();
		}
		sessionMap.put(userId, session);
		webSocketMap.put(chartId, sessionMap);
		}
		//推送真实人数消息 和虚拟人数
		int number=webSocketMap.get(chartId).size();
		Map<String, Object> map = new HashMap<>();
		Map<String, WebSocketSession> sessionMap1  = MyHandler.webSocketMap.get(GameConstants.SYS_OVERALL);
		RealNumber realNumber=new RealNumber();
		realNumber.setRoomNumber(chartId);
		realNumber.setRoomPeople(number);
		realNumber.setStatus("add");
		//查询是否有虚拟人数
		 List<Map<String, Object>> list=null;
		 int random =0;
		if(!StringUtils.isEmpty(chartId)&&!chartId.equals("sys_Overall")) {
			list=operationalSetService.queryVirtualNumberSetByNum(chartId);
			 if(list!=null && list.size()>=1) {
				  String randoms = this.redisFeignClient.get(chartId);
				  if(!StringUtils.isEmpty(randoms)) {
					  random = Integer.parseInt(randoms);
				  }

			 }else {
				 this.redisFeignClient.delete(chartId);
			 }
		}
		realNumber.setRandomNumber(random);
		map.put("roomRealNumber", realNumber);
		TextMessage message = new TextMessage(JSONObject.toJSONString(map));
		if (sessionMap1 != null) {
			Iterator<Entry<String, WebSocketSession>> it = sessionMap1.entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, WebSocketSession> tmpSession = it.next();
				if(!StringUtils.isEmpty(tmpSession.getValue())) {
					sendMessageToUser(tmpSession.getValue(), message);
				}
			}
		}
	}

	/**
	 * 出现异常的时候
	 */
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		if (session.isOpen()) {
			session.close();
		}
		String chartId = (String) session.getAttributes().get("chartId");
		String userId = (String) session.getAttributes().get("userId");
		String randomUserId= (String) session.getAttributes().get("randomUserId");
		webSocketMap.get(chartId).remove(userId);
		webSocketMap.get(GameConstants.SYS_OVERALL).remove(randomUserId);
	}

	/**
	 * 退出聊天的时候
	 */
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		String chartId = (String) session.getAttributes().get("chartId");
		String userId = (String) session.getAttributes().get("userId");
		String randomUserId= (String) session.getAttributes().get("randomUserId");
		if (webSocketMap.get(chartId) != null) {
			webSocketMap.get(chartId).remove(userId);
		}

		//Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
		//发送消息
		Map<String, WebSocketSession> sessionMap1  = MyHandler.webSocketMap.get(GameConstants.SYS_OVERALL);
		if(sessionMap1!=null) {
			sessionMap1.remove(randomUserId);
		}

		int number=webSocketMap.get(chartId).size();
		Map<String, Object> map = new HashMap<>();
		RealNumber realNumber=new RealNumber();
		realNumber.setRoomNumber(chartId);
		realNumber.setRoomPeople(number);
		map.put("roomRealNumber", realNumber);
		realNumber.setRoomPeople(number);
		realNumber.setStatus("reduce");
		//查询是否有虚拟人数
		 List<Map<String, Object>> list=null;
		 int random =0;
		 if(!StringUtils.isEmpty(chartId) && !chartId.equals("sys_Overall")) {
				list=operationalSetService.queryVirtualNumberSetByNum(chartId);
				 if(list!=null && list.size()>=1) {
					 String randoms = this.redisFeignClient.get(chartId);
					  if(!StringUtils.isEmpty(randoms)) {
						  random = Integer.parseInt(randoms);
					  }

				 }else {
					 this.redisFeignClient.delete(chartId);
				 }
			}
		realNumber.setRandomNumber(random);
		map.put("roomRealNumber", realNumber);
		 TextMessage message = new TextMessage(JSONObject.toJSONString(map));
		 if (sessionMap1!= null) {
				Iterator<Entry<String, WebSocketSession>> it = sessionMap1.entrySet().iterator();
				while (it.hasNext()) {
						Entry<String, WebSocketSession> tmpSession = it.next();
						if(!StringUtils.isEmpty(tmpSession.getValue())) {
							sendMessageToUser(tmpSession.getValue(), message);
						}

				}
			}
	}

	/**
	 * 发消息（无论是否在线）
	 *
	 * @param user
	 * @param message
	 */
	public static void sendMessageToUser(WebSocketSession user, TextMessage message) {
		if (user != null) {
			synchronized (user) {
				try {
					user.sendMessage(message);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 发消息给所有人
	 * @param chartId 消息类型
	 * @param message 消息文本
	 */
    public static void sendMessageToAllUser(String chartId, TextMessage message) {
        Map<String, WebSocketSession> sessionMap = webSocketMap.get(chartId);
        if (sessionMap != null) {
            Iterator<Entry<String, WebSocketSession>> it = sessionMap.entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, WebSocketSession> tmpSession = it.next();
                sendMessageToUser(tmpSession.getValue(), message);
            }
        }
    }
}
